package com.xzlf.netty;

import com.xzlf.Dir;
import com.xzlf.Group;
import com.xzlf.Tank;
import com.xzlf.TankFrame;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import java.io.*;
import java.util.UUID;

@AllArgsConstructor
@NoArgsConstructor
public class TankJoinMsg extends Msg{
    public int x, y;
    public Dir dir;

    public boolean moving;
    public Group group;

    public int length;
    public TankJoinMsg(Tank tank) {
        this.x = tank.getX();
        this.y = tank.getY();
        this.dir = tank.getDir();
        this.moving = tank.isMoving();
        this.group = tank.getGroup();
        this.id = tank.getId();
        this.msgType = MsgType.TankJoin;
        this.length = 33;
    }

    @Override
    public void handle() {
        if (TankFrame.INSTANCE.myTank.getId() == id)
            return;
        Tank tank = new Tank(x, y, dir, true, group, TankFrame.INSTANCE);
        if (TankFrame.INSTANCE.tankMap.get(id) == null){
            TankFrame.INSTANCE.tankMap.put(id, tank);
        }
        tank.setX(x);
        tank.setY(y);
        tank.setDir(dir);
        tank.setMoving(moving);
        tank.setGroup(group);
        tank.setId(id);
    }

    @Override
    public byte[] toBytes() {
        DataOutputStream dos = null;
        ByteArrayOutputStream bos = null;
        byte[] bytes = null;

        try {
            bos = new ByteArrayOutputStream();
            dos = new DataOutputStream(bos);
            dos.writeInt(MsgType.TankJoin.ordinal());
            dos.writeInt(33);
            dos.writeInt(x);
            dos.writeInt(y);
            dos.writeInt(dir.ordinal());
            dos.writeBoolean(moving);
            dos.writeInt(group.ordinal());
            dos.writeLong(id.getMostSignificantBits());
            dos.writeLong(id.getLeastSignificantBits());
            dos.flush();
            bytes = bos.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (bos != null)
                    bos.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            try {
                if (dos != null)
                    dos.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

        }
        return bytes;
    }

    @Override
    public void parseBytes(byte[] bytes) {

        DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes));
        try {
            x = dis.readInt();
            y = dis.readInt();
            dir = Dir.values()[dis.readInt()];
            moving = dis.readBoolean();
            group = Group.values()[dis.readInt()];
            id = new UUID(dis.readLong(), dis.readLong());

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (dis != null){
                try {
                    dis.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    @Override
    public MsgType getMsgType() {
        return msgType;
    }
}
